package cn.myzqu.sign.common.miniprogram.qrcode;

import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

/**
 * 微信小程序二维码
 * @Author: 的川
 * @Date: 2018/12/2
 */
@Data
@Slf4j
public class QRCode {


    /**
     * 请求地址
     */
    private String url;
    /**
     * 请求参数
     */
    private Params params = new Params();

    @Data
    class Params{
        /**必填
         * 最大32个可见字符，只支持数字，大小写英文以及部分特殊字符：!#$&'()*+,/:;=?@-._~，
         * 其它字符请自行编码为合法字符（因不支持%，中文无法使用 urlencode 处理，请使用其他编码方式）
         */
        private String scene;
        /**
         * 非必填
         * 必须是已经发布的小程序存在的页面（否则报错），例如 pages/index/index,
         * 根路径前不要填加 /,不能携带参数（参数请放在scene字段里），如果不填写这个字段，默认跳主页面
         */
        private String page;
        /**
         * 非必填，默认430
         * 二维码的宽度，单位 px，最小 280px，最大 1280px
         */
        private Integer width;
        /**
         * 非必填，默认false
         * 自动配置线条颜色，如果颜色依然是黑色，则说明不建议配置主色调，默认 false
         * false为黑色、true为根据logo自动配色
         */
        private Boolean auto_color;

        /**
         * 非必填，默认false
         * 是否需要透明底色，为 true 时，生成透明底色的小程序
         */
        private Boolean is_hyaline;

    }

    public QRCode() {
        params.scene = "demo";
    }

    public QRCode(String scene, String page) {
        params.scene = scene;
        params.page = page;
    }

    public QRCode(String scene, String page, Integer width, Boolean auto_color) {
        params.scene = scene;
        params.page = page;
        params.width = width;
        params.auto_color = auto_color;
    }

    /**
     * 将InputStream转byte
     * @param inputStream
     * @return
     */
    private byte[] inputStreamToByte(InputStream inputStream){
        try {
            ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
            byte[] buff = new byte[1024];
            int rc = 0;
            while ((rc = inputStream.read(buff, 0, 1024)) > 0) {
                swapStream.write(buff, 0, rc);
            }
            return swapStream.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;

    }

    /**
     * 获取小程序码，适用于需要的码数量极多的业务场景。通过该接口生成的小程序码，永久有效，数量暂无限制。
     * 接口 B 调用分钟频率受限(5000次/分钟)，如需大量小程序码，建议预生成。
     * @param imgPath
     * @param imgName
     * @return
     */
    public File getWXACodeUnlimit(String token,String imgPath, String imgName){
        byte[] bytes = getWXACodeUnlimit(token);
        //保存为图片在本地
        return saveFileByByte(bytes, imgPath, imgName);
    }

    public byte[] getWXACodeUnlimit(String token){
        this.url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + token;
        log.info("向腾讯服务器发送生成微信小程序二维码请求");
        String paramsJson = JSONObject.toJSONString(params);
        log.info("发送请求的地址："+url);
        log.info("发送请求的参数："+paramsJson);
        //发送post请求
        InputStream inputStream = postByJson(url,paramsJson);
        byte[] bytes = inputStreamToByte(inputStream);
        String str = new String(bytes);
        if(str.contains("errcode")){
            log.error("请求腾讯服务器生成二维码失败："+str);
            return null;
        }
        return bytes;
    }


    /**
     * 将bytes写入文件
     * @param bytes
     * @param imgPath
     * @param imgName
     * @return
     */
    private File saveFileByByte(byte[] bytes, String imgPath, String imgName){
        File file ;
        file = new File(imgPath,imgName);
        if(file.exists()){
            file.delete();
        }
        try{
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(bytes,0,bytes.length);
            fos.flush();
            fos.close();
        }catch (Exception e) {
            e.printStackTrace();
        } finally {

        }
        return file;
    }

    /**
     * post请求
     * @param httpUrl
     * @param json json串
     * @return
     * @throws Exception
     */
    public static InputStream postByJson(String httpUrl, String json)  {
        URL url = null;
        try {
            url = new URL(httpUrl);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        HttpURLConnection connection ;
        try {
            connection = (HttpURLConnection) url.openConnection();
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setUseCaches(false);
            connection.setInstanceFollowRedirects(true);
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Accept", "application/json");
            connection.setRequestProperty("Content-Type", "application/json");
            connection.connect();
            OutputStreamWriter out ;
            out = new OutputStreamWriter(connection.getOutputStream(), "UTF-8");
            out.append(json);
            out.flush();
            out.close();
            int code = connection.getResponseCode();
            InputStream is ;
            if (code == 200) {
                is = connection.getInputStream();
            }else{
                is = connection.getErrorStream();
            }
            return is;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

}
